<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048游戏</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#faf8ef',
                        secondary: '#bbada0',
                        cellEmpty: '#cdc1b4',
                        cell2: '#eee4da',
                        cell4: '#ede0c8',
                        cell8: '#f2b179',
                        cell16: '#f59563',
                        cell32: '#f67c5f',
                        cell64: '#f65e3b',
                        cell128: '#edcf72',
                        cell256: '#edcc61',
                        cell512: '#edc850',
                        cell1024: '#edc53f',
                        cell2048: '#edc22e',
                        textDark: '#776e65',
                        textLight: '#f9f6f2'
                    },
                    fontFamily: {
                        game: ['"Clear Sans"', '"Helvetica Neue"', 'Arial', 'sans-serif']
                    }
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .game-grid {
                background-color: #bbada0;
                padding: 15px;
                border-radius: 6px;
                display: inline-block;
            }
            .cell {
                width: 100px;
                height: 100px;
                margin: 7px;
                border-radius: 3px;
                background-color: rgba(238, 228, 218, 0.35);
                display: flex;
                justify-content: center;
                align-items: center;
                font-weight: bold;
                transition: all 0.2s ease;
            }
            @media (max-width: 500px) {
                .cell {
                    width: 60px;
                    height: 60px;
                    margin: 5px;
                }
            }
        }
    </style>
    <style>
        body {
            background-image: url('https://picsum.photos/id/1040/1920/1080');
            background-size: cover;
            background-position: center;
            background-attachment: fixed;
        }
        .game-container {
            backdrop-filter: blur(5px);
            background-color: rgba(250, 248, 239, 0.8);
            border-radius: 10px;
            padding: 20px;
        }
    </style>
</head>
<body class="font-game min-h-screen flex flex-col items-center justify-center p-4">
    <div class="max-w-md w-full">
        <header class="flex flex-col md:flex-row justify-between items-center mb-6">
            <div>
                <h1 class="text-[clamp(2.5rem,5vw,3.5rem)] font-bold text-textDark mb-2">2048</h1>
                <p class="text-textDark/80 text-lg">合并数字，得到 <strong>2048 方块！</strong></p>
            </div>
            <div class="flex gap-3 mt-4 md:mt-0">
                <div class="bg-secondary rounded-md p-2 text-center">
                    <div class="text-xs text-textLight/80">分数</div>
                    <div class="text-xl font-bold text-textLight" id="score">0</div>
                </div>
                <div class="bg-secondary rounded-md p-2 text-center">
                    <div class="text-xs text-textLight/80">最高分</div>
                    <div class="text-xl font-bold text-textLight" id="best-score">0</div>
                </div>
            </div>
        </header>

        <button id="new-game" class="bg-cell8 hover:bg-cell16 text-white font-bold py-2 px-4 rounded-md transition-colors mb-6">
            <i class="fa fa-refresh mr-2"></i>新游戏
        </button>

        <div class="game-container relative">
            <div class="game-grid">
                <div class="grid grid-cols-4" id="grid"></div>
            </div>
            <div id="game-message" class="absolute inset-0 bg-black/50 rounded-md flex items-center justify-center text-white text-3xl font-bold hidden">
                <div class="text-center">
                    <div id="game-message-text"></div>
                    <button id="try-again" class="bg-cell8 hover:bg-cell16 text-white font-bold py-2 px-4 rounded-md mt-4 transition-colors">
                        再试一次
                    </button>
                </div>
            </div>
        </div>

        <div class="mt-8 text-textDark/80">
            <h3 class="font-bold mb-2">游戏玩法：</h3>
            <p>使用 <strong>方向键</strong> 移动方块。当两个相同数字的方块相遇时，它们会 <strong>合并成一个！</strong></p>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 游戏棋盘设置
            const grid = document.getElementById('grid');
            const scoreDisplay = document.getElementById('score');
            const bestScoreDisplay = document.getElementById('best-score');
            const newGameButton = document.getElementById('new-game');
            const tryAgainButton = document.getElementById('try-again');
            const gameMessage = document.getElementById('game-message');
            const gameMessageText = document.getElementById('game-message-text');
            
            let board = [];
            let score = 0;
            let bestScore = localStorage.getItem('2048-best-score') || 0;
            let gameOver = false;
            let won = false;
            
            bestScoreDisplay.textContent = bestScore;
            
            // 初始化游戏棋盘
            function initBoard() {
                board = Array(4).fill().map(() => Array(4).fill(0));
                score = 0;
                scoreDisplay.textContent = score;
                gameOver = false;
                won = false;
                gameMessage.classList.add('hidden');
                
                // 清空棋盘
                grid.innerHTML = '';
                
                // 创建单元格
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        const cell = document.createElement('div');
                        cell.className = 'cell';
                        cell.id = `cell-${i}-${j}`;
                        grid.appendChild(cell);
                    }
                }
                
                // 添加初始方块
                addRandomTile();
                addRandomTile();
                updateBoard();
            }
            
            // 向棋盘添加随机方块(2或4)
            function addRandomTile() {
                if (!hasEmptyCell()) return;
                
                let emptyCells = [];
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (board[i][j] === 0) {
                            emptyCells.push({i, j});
                        }
                    }
                }
                
                const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                const value = Math.random() < 0.9 ? 2 : 4;
                
                board[randomCell.i][randomCell.j] = value;
            }
            
            // 更新棋盘显示
            function updateBoard() {
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        const cell = document.getElementById(`cell-${i}-${j}`);
                        const value = board[i][j];
                        
                        // 移除所有数字类
                        cell.className = 'cell';
                        
                        // 根据值添加适当的类
                        switch(value) {
                            case 0: cell.classList.add('bg-cellEmpty'); break;
                            case 2: cell.classList.add('bg-cell2', 'text-textDark', 'text-[clamp(2rem,4vw,2.5rem)]'); break;
                            case 4: cell.classList.add('bg-cell4', 'text-textDark', 'text-[clamp(2rem,4vw,2.5rem)]'); break;
                            case 8: cell.classList.add('bg-cell8', 'text-textLight', 'text-[clamp(2rem,4vw,2.5rem)]'); break;
                            case 16: cell.classList.add('bg-cell16', 'text-textLight', 'text-[clamp(1.8rem,3vw,2.2rem)]'); break;
                            case 32: cell.classList.add('bg-cell32', 'text-textLight', 'text-[clamp(1.8rem,3vw,2.2rem)]'); break;
                            case 64: cell.classList.add('bg-cell64', 'text-textLight', 'text-[clamp(1.8rem,3vw,2.2rem)]'); break;
                            case 128: cell.classList.add('bg-cell128', 'text-textLight', 'text-[clamp(1.5rem,2vw,1.8rem)]'); break;
                            case 256: cell.classList.add('bg-cell256', 'text-textLight', 'text-[clamp(1.5rem,2vw,1.8rem)]'); break;
                            case 512: cell.classList.add('bg-cell512', 'text-textLight', 'text-[clamp(1.5rem,2vw,1.8rem)]'); break;
                            case 1024: cell.classList.add('bg-cell1024', 'text-textLight', 'text-[clamp(1.2rem,1.8vw,1.5rem)]'); break;
                            case 2048: cell.classList.add('bg-cell2048', 'text-textLight', 'text-[clamp(1.2rem,1.8vw,1.5rem)]'); break;
                            default: cell.classList.add('bg-cell2048', 'text-textLight', 'text-[clamp(1rem,1.5vw,1.2rem)]'); break;
                        }
                        
                        cell.textContent = value === 0 ? '' : value;
                    }
                }
                
                // 检查游戏状态
                if (won) {
                    gameMessageText.textContent = '你赢了！';
                    gameMessage.classList.remove('hidden');
                    return;
                }
                
                if (gameOver) {
                    gameMessageText.textContent = '游戏结束！';
                    gameMessage.classList.remove('hidden');
                    return;
                }
            }
            
            // 检查是否有空单元格
            function hasEmptyCell() {
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (board[i][j] === 0) {
                            return true;
                        }
                    }
                }
                return false;
            }
            
            // 向上移动方块
            function moveUp() {
                let moved = false;
                
                for (let j = 0; j < 4; j++) {
                    // 压缩列
                    for (let i = 1; i < 4; i++) {
                        if (board[i][j] !== 0) {
                            let row = i;
                            while (row > 0 && board[row-1][j] === 0) {
                                board[row-1][j] = board[row][j];
                                board[row][j] = 0;
                                row--;
                                moved = true;
                            }
                        }
                    }
                    
                    // 合并方块
                    for (let i = 1; i < 4; i++) {
                        if (board[i][j] !== 0 && board[i][j] === board[i-1][j]) {
                            board[i-1][j] *= 2;
                            score += board[i-1][j];
                            board[i][j] = 0;
                            moved = true;
                            
                            // 检查胜利条件
                            if (board[i-1][j] === 2048) {
                                won = true;
                                return moved; // 胜利后停止进一步移动
                            }
                        }
                    }
                    
                    // 合并后再次压缩
                    for (let i = 1; i < 4; i++) {
                        if (board[i][j] !== 0) {
                            let row = i;
                            while (row > 0 && board[row-1][j] === 0) {
                                board[row-1][j] = board[row][j];
                                board[row][j] = 0;
                                row--;
                                moved = true;
                            }
                        }
                    }
                }
                
                return moved;
            }
            
            // 向下移动方块
            function moveDown() {
                let moved = false;
                
                for (let j = 0; j < 4; j++) {
                    // 压缩列
                    for (let i = 2; i >= 0; i--) {
                        if (board[i][j] !== 0) {
                            let row = i;
                            while (row < 3 && board[row+1][j] === 0) {
                                board[row+1][j] = board[row][j];
                                board[row][j] = 0;
                                row++;
                                moved = true;
                            }
                        }
                    }
                    
                    // 合并方块
                    for (let i = 2; i >= 0; i--) {
                        if (board[i][j] !== 0 && board[i][j] === board[i+1][j]) {
                            board[i+1][j] *= 2;
                            score += board[i+1][j];
                            board[i][j] = 0;
                            moved = true;
                            
                            // 检查胜利条件
                            if (board[i+1][j] === 2048) {
                                won = true;
                                return moved; // 胜利后停止进一步移动
                            }
                        }
                    }
                    
                    // 合并后再次压缩
                    for (let i = 2; i >= 0; i--) {
                        if (board[i][j] !== 0) {
                            let row = i;
                            while (row < 3 && board[row+1][j] === 0) {
                                board[row+1][j] = board[row][j];
                                board[row][j] = 0;
                                row++;
                                moved = true;
                            }
                        }
                    }
                }
                
                return moved;
            }
            
            // 向左移动方块
            function moveLeft() {
                let moved = false;
                
                for (let i = 0; i < 4; i++) {
                    // 压缩行
                    for (let j = 1; j < 4; j++) {
                        if (board[i][j] !== 0) {
                            let col = j;
                            while (col > 0 && board[i][col-1] === 0) {
                                board[i][col-1] = board[i][col];
                                board[i][col] = 0;
                                col--;
                                moved = true;
                            }
                        }
                    }
                    
                    // 合并方块
                    for (let j = 1; j < 4; j++) {
                        if (board[i][j] !== 0 && board[i][j] === board[i][j-1]) {
                            board[i][j-1] *= 2;
                            score += board[i][j-1];
                            board[i][j] = 0;
                            moved = true;
                            
                            // 检查胜利条件
                            if (board[i][j-1] === 2048) {
                                won = true;
                                return moved; // 胜利后停止进一步移动
                            }
                        }
                    }
                    
                    // 合并后再次压缩
                    for (let j = 1; j < 4; j++) {
                        if (board[i][j] !== 0) {
                            let col = j;
                            while (col > 0 && board[i][col-1] === 0) {
                                board[i][col-1] = board[i][col];
                                board[i][col] = 0;
                                col--;
                                moved = true;
                            }
                        }
                    }
                }
                
                return moved;
            }
            
            // 向右移动方块
            function moveRight() {
                let moved = false;
                
                for (let i = 0; i < 4; i++) {
                    // 压缩行
                    for (let j = 2; j >= 0; j--) {
                        if (board[i][j] !== 0) {
                            let col = j;
                            while (col < 3 && board[i][col+1] === 0) {
                                board[i][col+1] = board[i][col];
                                board[i][col] = 0;
                                col++;
                                moved = true;
                            }
                        }
                    }
                    
                    // 合并方块
                    for (let j = 2; j >= 0; j--) {
                        if (board[i][j] !== 0 && board[i][j] === board[i][j+1]) {
                            board[i][j+1] *= 2;
                            score += board[i][j+1];
                            board[i][j] = 0;
                            moved = true;
                            
                            // 检查胜利条件
                            if (board[i][j+1] === 2048) {
                                won = true;
                                return moved; // 胜利后停止进一步移动
                            }
                        }
                    }
                    
                    // 合并后再次压缩
                    for (let j = 2; j >= 0; j--) {
                        if (board[i][j] !== 0) {
                            let col = j;
                            while (col < 3 && board[i][col+1] === 0) {
                                board[i][col+1] = board[i][col];
                                board[i][col] = 0;
                                col++;
                                moved = true;
                            }
                        }
                    }
                }
                
                return moved;
            }
            
            // 检查游戏是否结束
            function checkGameOver() {
                // 如果有空单元格，游戏未结束
                if (hasEmptyCell()) return false;
                
                // 检查是否有水平方向可合并的方块
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 3; j++) {
                        if (board[i][j] === board[i][j+1]) {
                            return false;
                        }
                    }
                }
                
                // 检查是否有垂直方向可合并的方块
                for (let j = 0; j < 4; j++) {
                    for (let i = 0; i < 3; i++) {
                        if (board[i][j] === board[i+1][j]) {
                            return false;
                        }
                    }
                }
                
                // 没有可移动的步骤
                return true;
            }
            
            // 处理键盘控制
            function handleKeydown(e) {
                if (gameOver || won) return;
                
                let moved = false;
                
                switch(e.key) {
                    case 'ArrowUp':
                        moved = moveUp();
                        break;
                    case 'ArrowDown':
                        moved = moveDown();
                        break;
                    case 'ArrowLeft':
                        moved = moveLeft();
                        break;
                    case 'ArrowRight':
                        moved = moveRight();
                        break;
                    default:
                        return; // 不是有效按键
                }
                
                if (moved) {
                    scoreDisplay.textContent = score;
                    addRandomTile();
                    updateBoard();
                    
                    // 更新最高分
                    if (score > bestScore) {
                        bestScore = score;
                        bestScoreDisplay.textContent = bestScore;
                        localStorage.setItem('2048-best-score', bestScore);
                    }
                    
                    // 检查游戏是否结束
                    if (checkGameOver()) {
                        gameOver = true;
                        updateBoard();
                    }
                }
            }
            
            // 处理移动设备的触摸控制
            let touchStartX = 0;
            let touchStartY = 0;
            let touchEndX = 0;
            let touchEndY = 0;
            
            function handleTouchStart(e) {
                touchStartX = e.touches[0].clientX;
                touchStartY = e.touches[0].clientY;
            }
            
            function handleTouchEnd(e) {
                if (gameOver || won) return;
                
                touchEndX = e.changedTouches[0].clientX;
                touchEndY = e.changedTouches[0].clientY;
                
                const diffX = touchEndX - touchStartX;
                const diffY = touchEndY - touchStartY;
                
                // 根据差值大小确定滑动方向
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    // 水平滑动
                    if (diffX > 30) {
                        // 向右滑动
                        if (moveRight()) {
                            scoreDisplay.textContent = score;
                            addRandomTile();
                            updateBoard();
                            
                            if (score > bestScore) {
                                bestScore = score;
                                bestScoreDisplay.textContent = bestScore;
                                localStorage.setItem('2048-best-score', bestScore);
                            }
                            
                            if (checkGameOver()) {
                                gameOver = true;
                                updateBoard();
                            }
                        }
                    } else if (diffX < -30) {
                        // 向左滑动
                        if (moveLeft()) {
                            scoreDisplay.textContent = score;
                            addRandomTile();
                            updateBoard();
                            
                            if (score > bestScore) {
                                bestScore = score;
                                bestScoreDisplay.textContent = bestScore;
                                localStorage.setItem('2048-best-score', bestScore);
                            }
                            
                            if (checkGameOver()) {
                                gameOver = true;
                                updateBoard();
                            }
                        }
                    }
                } else {
                    // 垂直滑动
                    if (diffY > 30) {
                        // 向下滑动
                        if (moveDown()) {
                            scoreDisplay.textContent = score;
                            addRandomTile();
                            updateBoard();
                            
                            if (score > bestScore) {
                                bestScore = score;
                                bestScoreDisplay.textContent = bestScore;
                                localStorage.setItem('2048-best-score', bestScore);
                            }
                            
                            if (checkGameOver()) {
                                gameOver = true;
                                updateBoard();
                            }
                        }
                    } else if (diffY < -30) {
                        // 向上滑动
                        if (moveUp()) {
                            scoreDisplay.textContent = score;
                            addRandomTile();
                            updateBoard();
                            
                            if (score > bestScore) {
                                bestScore = score;
                                bestScoreDisplay.textContent = bestScore;
                                localStorage.setItem('2048-best-score', bestScore);
                            }
                            
                            if (checkGameOver()) {
                                gameOver = true;
                                updateBoard();
                            }
                        }
                    }
                }
            }
            
            // 事件监听器
            document.addEventListener('keydown', handleKeydown);
            document.addEventListener('touchstart', handleTouchStart);
            document.addEventListener('touchend', handleTouchEnd);
            newGameButton.addEventListener('click', initBoard);
            tryAgainButton.addEventListener('click', initBoard);
            
            // 初始化游戏
            initBoard();
        });
    </script>
</body>
</html>
    